package blog.gui;

import javax.microedition.media.*;
import javax.microedition.media.control.*;

import javax.microedition.lcdui.*;

import blog.SysRuntime;
import blog.controller.ConstAction;

import java.util.*;

/**
 * This class displays a list of blog entries in the entry cache.
 * The user can select one or more blog entries to post, edit, or delete.
 *
 */
public class CameraDisplay extends BaseCamDisplay implements IBaseGui
{
	Player player;

	VideoControl vc;

	protected static final String locator1 = "capture://video";

	protected static final String locator2 = "capture://video?encoding=yuv420";

	protected static final String locator3 = "capture://video?encoding=jpeg";

	protected static final String locator4 = "capture://video?encoding=jpeg&width=";

	protected static final int nLocators = 4;

	protected byte[] getCameraData(int width, int height) throws MediaException
	{
		byte[] newData = null;

		String availEncodings = System.getProperty( "video.snapshot.encodings" );
		String formatReq = null;
		String rawEncodingFormat = null;
		String encodingFormat = null;

		if (ENCODING_IMG_UNKNOWN == this.curReqEncoding)
		{
			//JPEG is our preferred format, suckas
			if ((-1 != availEncodings.indexOf( "jpeg" )) || (-1 != availEncodings.indexOf( "jpg" )))
				this.curReqEncoding = ENCODING_IMG_JPEG;
		}

		switch (this.curReqEncoding)
		{

		case (ENCODING_IMG_UNKNOWN):
		{
			//figure out which encoding is first in the list
			int firstPos = availEncodings.indexOf( "encoding=" );
			String firstEncoding = "jpeg";

			if (-1 != firstPos)
			{
				int secondPos = availEncodings.indexOf( "encoding=", firstPos + 1 );
				firstEncoding = availEncodings.substring( firstPos + 9, secondPos - 1 );
			}

			rawEncodingFormat = firstEncoding;

			if ((-1 != firstEncoding.indexOf( "jpeg" )) || (-1 != firstEncoding.indexOf( "jpg" )))
				this.curReqEncoding = ENCODING_IMG_JPEG;
			else if (-1 != firstEncoding.indexOf( "png" ))
				this.curReqEncoding = ENCODING_IMG_PNG;
			else if (-1 != firstEncoding.indexOf( "bmp" ))
				this.curReqEncoding = ENCODING_IMG_BMP;

		}
			break;

		case (ENCODING_IMG_JPEG):
		{
			if (-1 != availEncodings.indexOf( "jpeg" ))
				rawEncodingFormat = "jpeg";
			else if (-1 != availEncodings.indexOf( "jpg" ))
				rawEncodingFormat = "jpg";

		}
			break;

		case (ENCODING_IMG_PNG):
		{
			rawEncodingFormat = "png";
		}
			break;

		case (ENCODING_IMG_BMP):
		{
			rawEncodingFormat = "bmp";
		}
			break;

		}//switch

		encodingFormat = "encoding=" + rawEncodingFormat;
		formatReq = encodingFormat + IMG_FORMAT_WIDTH + width + IMG_FORMAT_HEIGHT + height;


		try
		{
			newData = vc.getSnapshot( formatReq );
		}
		catch (MediaException formatEx)
		{
			//retry with the  encoding format...
			try
			{
				newData = vc.getSnapshot( encodingFormat );
			}
			catch (MediaException encodingEx)
			{
				newData = vc.getSnapshot( rawEncodingFormat );
			}
		}

		return newData;
	}

	protected void doRecordPhoto()
	{

		try
		{
			player.stop( ); // "pause" the display of video data...
			int thumbWidth = 120, thumbHeight = 90;
			if (encodingWidth < thumbWidth)
			{
				thumbWidth = encodingWidth;
				thumbHeight = encodingHeight;
			}
			curMediaData = getCameraData( this.encodingWidth, this.encodingHeight );
			curThumbData = getCameraData( thumbWidth, thumbHeight );

			curMediaName = "img_" + String.valueOf( new Date( ).getTime( ) ); // + ".jpg"; //simple date hash
			snapShotImage = Image.createImage( this.curMediaData, 0, this.curMediaData.length );

		}
		catch (MediaException mediaEx)
		{
		}
		catch (Exception ex)
		{
		}
	}//recordPhoto

	protected int doInitCamera(int baseWidth, int baseHeight)
	{
		int sourceWidth, sourceHeight, leftX, topY;
		int thisViewWidth, thisViewHeight;
		int retVal = 0;

		try
		{

			String locator = "";

			for (int i = nLocators; i > 0; i--)
			{

				this.previewMediaType = "image/jpeg";

				switch (i)
				{
				case (4):
					locator = locator4 + +baseWidth + "&height=" + baseHeight;
					break;

				case (3):
					locator = locator3;
					break;

				case (2):
					locator = locator2;
					this.previewMediaType = "image/yuv420";
					break;

				case (1):
					locator = locator1;
					break;
				}

				try
				{
					player = Manager.createPlayer( locator );
				}
				catch (Exception ex)
				{
					continue; //fail...next freakin locator
				}

				break; //success-- exit the loop
			}

			player.realize( );
			vc = (VideoControl) player.getControl( "VideoControl" );

			vc.initDisplayMode( VideoControl.USE_DIRECT_VIDEO, this );
			sourceWidth = vc.getSourceWidth( );
			sourceHeight = vc.getSourceHeight( );

			thisViewWidth = this.getWidth( );
			thisViewHeight = this.getHeight( );
			
			viewWidth = Math.min( baseWidth, thisViewWidth-2 );
			viewHeight = Math.min( baseHeight, thisViewHeight-2 );

//			if (sourceWidth > thisViewWidth)
//			{
//				int scaleFactor;
//				scaleFactor = (sourceWidth / thisViewWidth);
//				if (scaleFactor == 0)
//					scaleFactor = 1;
//				viewWidth = sourceWidth / scaleFactor;
//				viewHeight = sourceHeight / scaleFactor;
//
//				//check again...if we're still too big, resize
//				if (viewWidth > baseWidth)
//				{
//					viewWidth = thisViewWidth;
//					viewHeight = thisViewHeight;
//				}
//			}
//			else
//			{
//				viewWidth = sourceWidth;
//				viewHeight = sourceHeight;
//			}
			vc.setDisplaySize( viewWidth, viewHeight );

			//center the view window, in case it's smaller than the screen
			leftX = (this.getWidth( ) - viewWidth) / 2;
			topY = (this.getHeight( ) - viewHeight) / 2;
			vc.setDisplayLocation( leftX, topY );

		}
		catch (MediaException mediaEx)
		{
		}
		catch (Exception ex)
		{
		}

		return retVal;
	}//initCamera

	protected void startCameraDisplay()
	{
		try
		{
			vc.setVisible( true );
			player.start( );
		}
		catch (MediaException mediaEx)
		{
		}
	}//startCameraDisplay

	public void doCleanup()
	{
		if (vc != null)
		{
			vc.setVisible( false );
			vc = null;
		}

		if (player != null)
		{
			player.close( );
			player = null;
		}
	}

	protected void doDisplayViewFinder()
	{
		startCameraDisplay( );
	}

	protected void doSetImageSize(int w, int h)
	{
		int newWidth, newHeight;
		super.doSetImageSize( w, h );

		if (vc != null)
			try
			{
				player.stop( );
				vc.setVisible( false );
//				if (w < viewWidth)
//				{
//					newWidth = w;
//					newHeight = h;
//				}
//				else
//				{
//					newWidth = viewWidth;
//					newHeight = viewHeight;
//				}
				viewWidth = Math.min( w, getWidth( )-2 );
				viewHeight = Math.min( h, getHeight( )-2 );

				vc.setDisplaySize( viewWidth, viewHeight );
				//center the view window, in case it's smaller than the screen
				int leftX = (this.getWidth( ) - viewWidth) / 2;
				int topY = (this.getHeight( ) - viewHeight) / 2;
				vc.setDisplayLocation( leftX, topY );

				vc.setVisible( true );
				player.start( ); //restart player
			}
			catch (MediaException mediaEx)
			{
			}

	}//doSetImageSize

	public Image getThumbnail()
	{
		return snapShotImage;
	}

	public void doSaveDataAndExit()
	{
		SysRuntime.actionManager.addAction(this, ConstAction.ACT_VIDEO_CAPTURE);
	}

	public int getIdentify() {
		return 9999;
	}

	public void notifyChanged(Object param) {
		
	}
}